#ifndef STRHELPER_H
#define STRHELPER_H
#include <string>
#include <regex>
#include <functional>
#include <wx/string.h>

template<typename TCON>
TCON & str_split(TCON & con,const typename TCON::value_type & str,const typename TCON::value_type & split_str)
{
    if(split_str.empty())
    {
        con.push_back(str);
        return con;
    }
    size_t pos=0;
    size_t npos;
    for(;;)
    {
        npos=str.find(split_str,pos);
        if(npos!=str.npos)
        {
            con.push_back(str.substr(pos,npos-pos));
            pos=npos+split_str.size();
        }else {
            con.push_back(str.substr(pos,str.size()-pos));
            break;
        }
    }
    return con;
}

template<typename TCON>
typename TCON::value_type str_join(const TCON & con,const typename TCON::value_type & join_str)
{
    if(con.empty())
        return  typename TCON::value_type();
    size_t nsz=(con.size()-1)*join_str.size();
    for(auto & ss:con)
    {
        nsz+=ss.size();
    }
    typename TCON::value_type str;
    str.reserve(nsz);
    auto pss=con.begin();
    str.append(*pss);
    ++pss;
    for(;pss!=con.end();++pss)
    {
        str.append(join_str);
        str.append(*pss);
    }
    return str;
}

std::wstring str_encode_to_jscode(const std::wstring& str);
std::string str_encode_to_jscode(const std::string& str);


std::string str_format(const char *pszFmt, ...);
std::wstring str_format(const wchar_t*pszFmt,...);
std::string regex_replace(const std::string & str, const std::regex & rgx,
    std::function<std::string(std::smatch&)> fun);
std::wstring regex_replace(const std::wstring & str, const std::wregex & rgx,
    std::function<std::wstring(std::wsmatch&)> fun);

std::string str_ltrim(const std::string & str,const char* trim_chars=NULL);
std::string str_rtrim(const std::string & str,const char* trim_chars=NULL);
std::string str_trim(const std::string & str,const char* trim_chars=NULL);


std::wstring str_ltrim(const std::wstring & str,const wchar_t * trim_chars=NULL);
std::wstring str_rtrim(const std::wstring & str,const wchar_t * trim_chars=NULL);
std::wstring str_trim(const std::wstring & str,const wchar_t * trim_chars=NULL);

std::string str_replace(const std::string & str,const std::string & fndstr,const std::string & repstr,size_t pos=0,size_t repcount=-1);

std::wstring str_replace(const std::wstring & str,const std::wstring & fndstr,const std::wstring & repstr,size_t pos=0,size_t repcount=-1);

std::wstring str_erase(const std::wstring & str,const std::wstring & fndstr,size_t pos=0,size_t repcount=-1);

std::string str_erase(const std::string & str,const std::string & fndstr,size_t pos=0,size_t repcount=-1);

inline int str_chr(const char* str,char ch)
{
    for(int i=0;str[i];++i)
    {
        if(str[i]==ch)
            return i;
    }
    return -1;
}
inline int str_chr(const wchar_t* str,wchar_t ch)
{
    for(int i=0;str[i];++i)
    {
        if(str[i]==ch)
            return i;
    }
    return -1;
}
inline std::string wxs2utf(const wxString & str)
{
    wxCharTypeBuffer<char> buf=str.ToUTF8();
    return std::string(buf.data(),buf.length());
}

inline wxString utf2wxs(const std::string & str)
{
    return wxString::FromUTF8(str);
}


std::string utf2s(const std::string & str);//utf8 to local ansi string
std::string s2utf(const std::string & str);

std::wstring s2ws(const std::string & str);
std::string  ws2s(const std::wstring & str);

std::string ws2utf(const std::wstring & str);
std::wstring utf2ws(const std::string & str);




#endif // STRHELPER_H
